import httplib, urllib, base64, time
import simplejson as json
import myLogger as logger
import caching
import user as usermod
import datetime

minutesPerHour = 60
secondsPerMinute = 60
apiCallsPerHour = 150
USERCACHE = r"./cache/user"

MyUserCache = caching.UserCache(USERCACHE)

def waitTime(seconds):
    def wait():
        print "waiting for API"
        time.sleep(seconds)
    return wait

waitForAPI = waitTime(minutesPerHour * secondsPerMinute / apiCallsPerHour)
#waitForAPI = waitTime(0)

def getConnection(url):
    return httplib.HTTPConnection(url)

def followers(user_id):
    conn = getConnection("twitter.com")
    conn.request("GET", "/followers/ids/" + user_id + ".json")
    resp = conn.getresponse()
    followers = resp.read()
    decoder = json.JSONDecoder()
    waitForAPI()
    return decoder.decode(followers)

def friends(user_id):
    conn = httplib.HTTPConnection("twitter.com")
    conn.request("GET", "/friends/ids/" + user_id + ".json")
    resp = conn.getresponse()
    friends = resp.read()
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    return decoder.decode(friends)

def inner_list_members(user_id, list_id, user, password, next_cursor=-1):
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text}
    conn = httplib.HTTPConnection("api.twitter.com")
    conn.request("GET", "/1/" + user_id + "/" + list_id + "/members" + ".json?cursor=" + str(next_cursor), None, header)
    resp = conn.getresponse()
    friends = resp.read()
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    return decoder.decode(friends)

def list_members(user_id, list_id, user, password):
    next_cursor = -1
    users = []
    while (next_cursor != 0):
        inner = inner_list_members(user_id, list_id, user, password, next_cursor)
        for u in inner["users"]:
            users.append(u)
        next_cursor = inner["next_cursor"]
    return users

def trends():
    conn = httplib.HTTPConnection("search.twitter.com")
    conn.request("GET", "/trends.json")
    resp = conn.getresponse()
    trends = resp.read()
    conn.close()
    decoder = json.JSONDecoder()
    return decoder.decode(trends)

def show_user(user_id):
    decoder = json.JSONDecoder()
    the_user = MyUserCache.readCache(user_id)
    if (the_user != None):
        age = datetime.datetime.now() - the_user.timestamp
        if (age > datetime.timedelta(days=-2)):
            return the_user.json
    else:    
        conn = httplib.HTTPConnection("twitter.com")
        conn.request("GET", "/users/show/" + str(user_id) + ".json")
        resp = conn.getresponse()
        userstuff = resp.read()
        conn.close()
        waitForAPI()
    the_user = usermod.user(userstuff)
    MyUserCache.writeCache(the_user)
    MyUserCache.saveCache()
    return the_user.json

def get_user(user_id):
    decoder = json.JSONDecoder()
    the_user = MyUserCache.readCache(user_id)
    if (the_user != None):
        age = datetime.datetime.now() - the_user.timestamp
        if (age > datetime.timedelta(days=-2)):
            return the_user
    else:    
        conn = httplib.HTTPConnection("twitter.com")
        conn.request("GET", "/users/show/" + str(user_id) + ".json")
        resp = conn.getresponse()
        userstuff = resp.read()
        conn.close()
        waitForAPI()
    the_user = usermod.user(userstuff)
    MyUserCache.writeCache(the_user)
    MyUserCache.saveCache()
    return the_user

def add_friend(user_to_add, user, password):
    logger.log("adding friend " + str(user_to_add))
    conn = httplib.HTTPConnection("twitter.com")
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text}
    conn.request("POST", "/friendships/create/" + str(user_to_add) + ".json", None, header)
    resp = conn.getresponse()
    userstuff = resp.read()
    logger.log(str(userstuff))
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    the_user = usermod.user(userstuff)
    MyUserCache.writeCache(the_user)
    MyUserCache.saveCache()
    return userstuff

def remove_friend(user_to_remove, user, password):
    logger.log("removing friend " + str(user_to_remove))
    conn = httplib.HTTPConnection("twitter.com")
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text}
    conn.request("POST", "/friendships/destroy/" + str(user_to_remove) + ".json", None, header)
    resp = conn.getresponse()
    userstuff = resp.read()
    logger.log(str(userstuff))
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    the_user = usermod.user(userstuff)
    MyUserCache.writeCache(the_user)
    MyUserCache.saveCache()
    return userstuff

def set_status(status, user, password):
    logger.log("setting status '" + status.strip("\n") + "'")
    conn = httplib.HTTPConnection("twitter.com")
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text,
                "Content-type" : "application/x-www-form-urlencoded",
                "Accept" : "text/plain"}
    params = urllib.urlencode({"status" : status})
    conn.request("POST", "/statuses/update.json", params, header)
    resp = conn.getresponse()
    userstuff = resp.read()
    logger.log(str(userstuff))
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    return userstuff

def remove_friends_of_another(another, user, pw):
    droplist = friends(another)
    follows = followers(user)
    for person in droplist:
        if person not in follows:
            remove_friend(person, user, pw)

def add_friends_of_another(another, user, pw):
    addlist = friends(another)
    follows = followers(user)
    for person in addlist:
        if person not in follows:
            add_friend(person, user, pw)

def add_followers_of_another(another, user, pw):
    addlist = followers(another)
    follows = followers(user)
    for person in addlist:
        if person not in follows:
            add_friend(person, user, pw)

def add_friend_list(addlist, current_friends, user, pw):
    for person in addlist:
        if person not in current_friends:
            add_friend(person, user, pw)

def count_diff(list1, list2):
    i = 0
    for item in list1:
        if item not in list2:
            i += 1
    return i

def find_bad_followers(user, minimum_quality):
    bad_list = []
    the_list = followers(user)
    for person in the_list:
        try:
            data = show_user(person)
            if quality(data) < minimum_quality:
                bad_list.append(person)
        except:
            pass
    return bad_list

def find_bad_friends(user, minimum_quality):
    bad_list = []
    the_list = friends(user)
    for person in the_list:
        try:
            data = show_user(person)
            if quality(data) < minimum_quality:
                bad_list.append(person)
        except:
            pass
    return bad_list

def block(user_to_remove, user, password):
    logger.log("blocking user " + str(user_to_remove))
    conn = httplib.HTTPConnection("twitter.com")
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text}
    conn.request("POST", "/blocks/create/" + str(user_to_remove) + ".json", None, header)
    resp = conn.getresponse()
    userstuff = resp.read()
    logger.log(str(userstuff))
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    return userstuff

def unblock(user_to_unblock, user, password):
    logger.log("unblocking user " + str(user_to_unblock))
    conn = httplib.HTTPConnection("twitter.com")
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text}
    conn.request("POST", "/blocks/destroy/" + str(user_to_unblock) + ".json", None, header)
    resp = conn.getresponse()
    userstuff = resp.read()
    logger.log(str(userstuff))
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    return userstuff

def blocked_users(user, password):
    conn = getConnection("twitter.com")
    header_text = base64.encodestring(user + ":" + password)
    header_text = "Basic " + header_text[:-1]
    header = {"Authorization" : header_text}
    conn.request("POST", "/blocks/blocking/ids.json", None, header)
    resp = conn.getresponse()
    userstuff = resp.read()
    conn.close()
    decoder = json.JSONDecoder()
    waitForAPI()
    return str(userstuff).strip("[").strip("]").split(",")

def ratio(user):
    try:
        followees = float(user['friends_count'])
        followers = float(user['followers_count'])
        value = followees / followers
    except:
        value = 0
    return value

def quality(user):
    try:
        return 1 / ratio(user)
    except:
        return 0.01

